<template>
    <div ref="ThreeRef" class="three">
    </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
    name: 'Three'
})
</script>
<script lang="ts" setup>
import { ref, onMounted, getCurrentInstance, nextTick } from "vue"
import * as THREE from "three"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import * as SceneUtils from 'three/examples/jsm/utils/SceneUtils'
const { proxy }: any = getCurrentInstance()
const init = async () => {
    // 创建场景
    await nextTick()
    const scene = new THREE.Scene()
    scene.background = new THREE.Color(0xffffff)
    const url = './MZI-3D.glb'
    const Three = proxy.$refs.ThreeRef
    const k = Three.offsetWidth / Three.offsetHeight
    // 创建相机
    const camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)
    camera.position.set(50, 30, -50)

    // 添加灯光
    const directionalLight = new THREE.DirectionalLight(0xffffff);
    directionalLight.position.set(5, 5, 5)
    directionalLight.castShadow = true
    scene.add(directionalLight);

    // 创建渲染器
    const renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.shadowMap.enabled = true
    renderer.setSize(Three.offsetWidth, Three.offsetHeight)
    Three.appendChild(renderer.domElement)

    const loader = new GLTFLoader()
    loader.load(
        url,
        (gltf) => {
            const model = gltf.scene
            model.scale.set(0.7, 0.7, 0.7) // 缩小模型
            model.castShadow = true
            const box = new THREE.Box3().setFromObject(model)
            const center = box.getCenter(new THREE.Vector3())
            model.position.sub(center) // 将模型位置移到原点处
            model.traverse(function (child) {
                if (child instanceof THREE.Mesh) {
                    const glassMaterial = new THREE.MeshPhysicalMaterial({
                        color: child.material.color,
                        transparent: true, // 透明度设置为 true
                        opacity: 0.8, // 设置透明度
                        roughness: 0,
                        metalness: 0,
                        envMapIntensity: 1,
                        transmission: 0.95, // 折射度，表示光线经过材料时的衰减程度
                        clearcoat: 1,
                        clearcoatRoughness: 0,
                        ior: 1.5, // 折射率，控制光的折射程度
                    });
                    child.frustumCulled = false
                    //模型阴影
                    child.castShadow = true
                    //模型自发光
                    // child.material.emissive = child.material.color
                    // child.material.emissiveMap = child.material.map
                    child.material = glassMaterial
                    // 模型透明度
                    // child.material.transparent = true
                    // child.material.opacity = 0.9
                }
            })
            scene.add(model)
        },
        (xhr) => {
            console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
        },
        (error) => {
            console.error('Failed to load model', error)
        }
    )
    window.addEventListener('resize', () => {
        // 更新相机投影矩阵
        camera.updateProjectionMatrix()
        // 重新设置渲染器渲染范围
        renderer.setSize(Three.offsetWidth, Three.offsetHeight)
    })
    const controls = new OrbitControls(camera, renderer.domElement)
    controls.enableDamping = true
    //是否可以缩放
    controls.enableZoom = true
    //是否自动旋转
    controls.autoRotate = true
    //设置相机距离原点的最近距离
    controls.minDistance = 50
    //设置相机距离原点的最远距离
    controls.maxDistance = 600
    //是否开启右键拖拽
    controls.enablePan = true
    // 渲染场景
    const animate = () => {
        requestAnimationFrame(animate)
        renderer.render(scene, camera)
    }

    animate()
}

defineExpose({
    init
})
</script>
<style>
.three {
    width: 100%;
    height: 100%;
}
</style>